#include "../include/processor.h"

extern std::fstream disk;
extern Table gdt[4096];
extern byte ram[MAX_MEM];

qword iregs[128];
real4 fregs[32];
real8 dregs[32];
VREG vregs[64];

void set_valueI(qword value, byte reg)
{
	iregs[reg] = (qword)value;
}
void set_valueF(real4 value, byte reg)
{
	fregs[(reg & 0x1f)] = (real4)value;
}
void set_valueD(real8 value, byte reg)
{
	dregs[(reg & 0x3f)] = (real8)value;
}
void set_valueV(VREG value, byte reg)
{
	vregs[(reg & 0x1f)] = value;
}

inline void read_mem(qword address, byte reg, byte size)
{
	if (reg < 128)
		memcpy(iregs + reg, ram + address, size);
	else if (reg < 160)
		memcpy(fregs + (reg & 0x1f), ram + address, size);
	else if (reg < 192)
		memcpy(dregs + (reg & 0x1f), ram + address, size);
	else
		memcpy(vregs + (reg & 0x3f), ram + address, size);
}
inline void write_mem(qword address, byte reg, byte size)
{
	if (reg < 128)
		memcpy(ram + address, iregs + reg, size);
	else if (reg < 160)
		memcpy(ram + address, fregs + (reg & 0x1f), size);
	else if (reg < 192)
		memcpy(ram + address, dregs + (reg & 0x1f), size);
	else
		memcpy(ram + address, vregs + (reg & 0x3f), size);
}
inline void changeFlag(byte reg)
{
	iregs[Flag] &= ~POS;
	iregs[Flag] &= ~NEG;
	iregs[Flag] &= ~ZERO;
	if (reg < 128)
	{
		if (iregs[reg] == 0)
			iregs[Flag] |= ZERO;
		else if ((long long)iregs[reg] < 0)
			iregs[Flag] |= NEG;
		else
			iregs[Flag] |= POS;
	}
	else if (reg < 160)
	{
		if (fabsf(fregs[(reg & 0x1f)]) < 1e-64)
			iregs[Flag] |= ZERO;
		else if (fregs[(reg & 0x1f)] < 0)
			iregs[Flag] |= NEG;
		else
			iregs[Flag] |= POS;
	}
	else if (reg < 192)
	{
		if (fabs(dregs[reg & 0x1f]) < 1e-512)
			iregs[Flag] |= ZERO;
		else if (dregs[(reg & 0x1f)] < 0)
			iregs[Flag] |= NEG;
		else
			iregs[Flag] |= POS;
	}
	else
	{
		// TODO:Throw Error:Reg Type Error
	}
}